<?php
/**
 *      [迷你云] (C)2009-2012 南京恒为网络科技.
 *   软件仅供研究与学习使用，如需商用，请访问www.miniyun.cn获得授权
 * 
 */
?>
<?php


class MComponent
{
    public $_m = array();

    
    public function __get($name)
    {
                                $get_func = 'get'.$name;
        if (method_exists($this, $get_func))
        {
            return $this->$get_func();
        }
        
                                else if (isset($this->_m[$name]))
        {
            return $this->_m[$name];
        }

                                else if (isset($this->$name))
        {
            return $this->$name;
        }

                                else if (is_array($this->_m))
        {
            foreach($this->_m as $object)
            {
                if (property_exists($object,$name) || $object->canGetProperty($name))
                    return $object->$name;
            }
        }

        throw new Exception(FXP::t('Property "{class}.{property}" is not defined.',
            array('{class}'=>get_class($this), '{property}'=>$name)));
    }

    
    public function __set($name, $value)
    {
                                $set_func = 'set'.$name;
        if (method_exists($this, $set_func))
        {
            return $this->$set_func($value);
        }

                                $this->_m[$name] = $value;
    }

    
    public function __isset($name)
    {
        $get_func = 'get'.$name;
        if (method_exists($this, $get_func))
            return $this->$get_func() !== null;

        else if(is_array($this->_m))
        {
            if (isset($this->_m[$name]))
                return true;
        }
        return false;
    }

    
    public function __unset($name)
    {
        $set_fun ='set'.$name;
        if (method_exists($this, $set_fun))
            $this->$set_fun(null);

        else if(is_array($this->_m))
        {
            if (isset($this->_m[$name]))
                $this->_m[$name] = null;
            else
            {
                foreach($this->_m as $object)
                {
                    if (property_exists($object,$name))
                        return $object->$name = null;
                    else if ($object->canSetProperty($name))
                        return $object->$setter(null);
                }
            }
        }
        
        else if (method_exists($this, 'get'.$name))
            throw new Exception(FXP::t('Property "{class}.{property}" is read only.',
                array('{class}'=>get_class($this), '{property}'=>$name)));
    }

    
    public function __call($name, $parameters)
    {
        if ($this->_m !== null)
        {
            foreach($this->_m as $object)
            {
                if (method_exists($object, $name))
                    return call_user_func_array(
                        array($object, $name),
                        $parameters
                        );
            }
        }
        
        if (class_exists('Closure', false) && 
            $this->canGetProperty($name) && 
            $this->$name instanceof Closure)
        {
            return call_user_func_array($this->$name, $parameters);
        }

        throw new Exception(FXP::t('{class} and its behaviors do not have a method or closure named "{name}".',
            array('{class}'=>get_class($this), '{name}'=>$name)));
    }

    
    public function hasProperty($name)
    {
        return method_exists($this, 'get'.$name) || method_exists($this, 'set'.$name);
    }

    
    public function canGetProperty($name)
    {
        return method_exists($this, 'get'.$name);
    }

    
    public function canSetProperty($name)
    {
        return method_exists($this,'set'.$name);
    }
}
?>